package com.cym.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.RuntimeUtil;
import com.github.odiszapc.nginxparser.NgxConfig;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class NginxUtils {

    /**
     * 判断nginx是否运行
     *
     * @return
     */
    public static boolean isRun() {
        boolean isRun = false;
        if (SystemTool.isWindows()) {
            String[] command = {"tasklist"};
            String rs = RuntimeUtil.execForStr(command);
            isRun = rs.toLowerCase().contains("nginx.exe");
        } else {
            String[] command = {"/bin/sh", "-c", "ps -ef|grep nginx"};
            String rs = RuntimeUtil.execForStr(command);
            isRun = rs.contains("nginx: master process") || rs.contains("nginx: worker process");
        }

        return isRun;
    }

    /**
     * 重新创建配置文件，删除影响解析的行（比如#号开头，但是此行没有其他内容）
     *
     * @param nginxPath 配置文件路径
     * @return java.lang.String
     * @author by yanglei 2020/7/5 21:17
     */
    public static String initNginx(String nginxPath) {
        // 删除一行内容（java本身没有删除的方法，本方法通过先读取文件的内容（需删除的行数除外），放到list中，在重新写入）
        List<String> lines = FileUtil.readLines(nginxPath, CharsetUtil.CHARSET_UTF_8);
        List<String> rs = new ArrayList<>();
        for (String str : lines) {
            if (str.trim().indexOf("#") == 0) {
                continue;
            }
            rs.add(str);
        }

        String initNginxPath = FileUtil.getTmpDirPath() + UUID.randomUUID();
        FileUtil.writeLines(rs, initNginxPath, CharsetUtil.CHARSET_UTF_8);
        // 删除原文件
        FileUtil.del(nginxPath);
        return initNginxPath;
    }

    /**
     * 读取nginx配置
     * @param nginxPath 配置文件路径
     * @return /
     */
    public static NgxConfig readByNginxPath(String nginxPath) throws Exception {
        try {
            return NgxConfig.read(nginxPath);
        } catch (IOException e) {
            throw new Exception("文件读取失败:" + e.getMessage());
        }
    }

    /**
     * 负载均衡工具
     */
    public static class UpStream {
        private static final String SERVER_REG = "(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5]):(\\d+)";
        private static final String MAX_FAILS_REG = "max_fails=(\\d+)";
        private static final String FAIL_TIMEOUT_REG = "fail_timeout=(\\d+)s";
        private static final String WEIGHT_REG = "weight=(\\d+)";
        /**
         * 解析IP和端口
         * @param str 需要解析的字符串
         * @return /
         */
        public static String[] regServerPort(String str) {
            return ReUtil.getGroup0(SERVER_REG, str).split(":");
        }

        /**
         * 提取最大失败次数
         * @param str 解析串
         * @param defaultVal 默认值
         * @return /
         */
        public static Integer regMaxFails(String str, Integer defaultVal) {
            return ReUtil.contains(MAX_FAILS_REG, str) ? Integer.parseInt(ReUtil.getGroup1(MAX_FAILS_REG, str)) : defaultVal;
        }

        /**
         * 提取失败周期
         * @param str 解析串
         * @param defaultVal 默认值
         * @return /
         */
        public static Integer regFailTimeout(String str, Integer defaultVal) {
            return ReUtil.contains(FAIL_TIMEOUT_REG, str) ? Integer.parseInt(ReUtil.getGroup1(FAIL_TIMEOUT_REG, str)) : defaultVal;
        }

        /**
         * 提取权重
         * @param str 解析串
         * @param defaultVal 默认值
         * @return /
         */
        public static Integer regWeight(String str, Integer defaultVal) {
            return ReUtil.contains(WEIGHT_REG, str) ? Integer.parseInt(ReUtil.getGroup1(WEIGHT_REG, str)) : defaultVal;
        }
    }
}
